package com.umeox.watch.moto.dataservice.mqtt;

import static com.umeox.watch.moto.dataservice.db.ThirdPartyDataBaseUtils.deletePhoneContacts;
import static com.umeox.watch.moto.dataservice.db.ThirdPartyDataBaseUtils.savePhoneContacts;

import android.content.ContentProviderOperation;
import android.content.ContentValues;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Build;
import android.text.TextUtils;

import androidx.work.ExistingWorkPolicy;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.umeox.moto.common.log.Logger;
import com.umeox.moto.common.utils.AndroidUtils;
import com.umeox.moto.common.utils.GsonUtils;
import com.umeox.moto.common.utils.NetUtils;
import com.umeox.watch.moto.apiclient.model.AlarmDTO;
import com.umeox.watch.moto.apiclient.model.BuddyDTO;
import com.umeox.watch.moto.apiclient.model.ContactDTO;
import com.umeox.watch.moto.apiclient.model.DeviceCodeDTO;
import com.umeox.watch.moto.apiclient.model.DeviceConfigDTO;
import com.umeox.watch.moto.apiclient.model.FencesDTO;
import com.umeox.watch.moto.apiclient.model.ForbidPeriodDTO;
import com.umeox.watch.moto.apiclient.model.HolderInfoDTO;
import com.umeox.watch.moto.apiclient.model.IMGroupDTO;
import com.umeox.watch.moto.apiclient.model.LocFrequenceDTO;
import com.umeox.watch.moto.apiclient.model.PrayerSettingDTO;
import com.umeox.watch.moto.apiclient.model.QuranLearnChallengeDTO;
import com.umeox.watch.moto.apiclient.model.SOSEventDTO;
import com.umeox.watch.moto.apiclient.model.SportChallengeDTO;
import com.umeox.watch.moto.apiclient.model.TasksAttributeDTO;
import com.umeox.watch.moto.apiclient.model.WifiDTO;
import com.umeox.watch.moto.dataservice.DataProvider;
import com.umeox.watch.moto.dataservice.base.BaseApp;
import com.umeox.watch.moto.dataservice.base.LauncherManager;
import com.umeox.watch.moto.dataservice.constants.Constants;
import com.umeox.watch.moto.dataservice.constants.InternalConstant;
import com.umeox.watch.moto.dataservice.constants.MqttConstants;
import com.umeox.watch.moto.dataservice.db.AppDataBase;
import com.umeox.watch.moto.dataservice.db.dao.AlarmDao;
import com.umeox.watch.moto.dataservice.db.dao.BuddyDao;
import com.umeox.watch.moto.dataservice.db.dao.ContactDao;
import com.umeox.watch.moto.dataservice.db.dao.DeviceCodeDao;
import com.umeox.watch.moto.dataservice.db.dao.DeviceDao;
import com.umeox.watch.moto.dataservice.db.dao.FencesDao;
import com.umeox.watch.moto.dataservice.db.dao.ForbidPeriodDao;
import com.umeox.watch.moto.dataservice.db.dao.GroupMemberDao;
import com.umeox.watch.moto.dataservice.db.dao.IMGroupDao;
import com.umeox.watch.moto.dataservice.db.dao.TasksAttributeDao;
import com.umeox.watch.moto.dataservice.db.model.AlarmClock;
import com.umeox.watch.moto.dataservice.db.model.BuddyInfo;
import com.umeox.watch.moto.dataservice.db.model.ContactInfo;
import com.umeox.watch.moto.dataservice.db.model.DeviceCode;
import com.umeox.watch.moto.dataservice.db.model.DeviceConfig;
import com.umeox.watch.moto.dataservice.db.model.Fences;
import com.umeox.watch.moto.dataservice.db.model.ForbidPeriod;
import com.umeox.watch.moto.dataservice.db.model.HolderInfo;
import com.umeox.watch.moto.dataservice.db.model.IMGroup;
import com.umeox.watch.moto.dataservice.db.model.IMGroupMember;
import com.umeox.watch.moto.dataservice.db.model.LocationPeriod;
import com.umeox.watch.moto.dataservice.db.model.PrayerSetting;
import com.umeox.watch.moto.dataservice.db.model.QuranLearn;
import com.umeox.watch.moto.dataservice.db.model.TasksAttribute;
import com.umeox.watch.moto.dataservice.mqtt.interfaces.IResultCallBack;
import com.umeox.watch.moto.dataservice.services.ApiService;
import com.umeox.watch.moto.dataservice.services.GeoFenceService;
import com.umeox.watch.moto.dataservice.services.LocationService;
import com.umeox.watch.moto.dataservice.utils.MMKVUtils;
import com.umeox.watch.moto.dataservice.utils.PushReceiverHelper;
import com.umeox.watch.moto.dataservice.utils.Utils;
import com.umeox.watch.moto.dataservice.work.DIWork;
import com.umeox.watch.moto.dataservice.work.UploadHotVerWork;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Created by Rambo 2020/5/12
 * Describe:数据处理，MQTT到达的消息数据都会经过这个类进行处理
 */
public class DataHandleManager<T> {

    private volatile static DataHandleManager instance;
    public static final String TAG_UPLOAD_HOT_VER_WORKER = "upload_hot_ver_worker";
    public static final String TAG_REPORT_DI = "report_di_worker";

    private DataHandleManager() {

    }

    public static DataHandleManager getInstance() {
        if (instance == null) {
            synchronized (DataHandleManager.class) {
                if (instance == null) {
                    instance = new DataHandleManager();
                }
            }
        }
        return instance;
    }

    private IResultCallBack<T> mResultCallBack;

    private HashMap<Integer, IResultCallBack<T>> chatMsgResultCallBacks;


    public void setResultCallBack(IResultCallBack<T> resultCallBack) {
        mResultCallBack = resultCallBack;
    }

    public void setChatMsgResultCallBack(Integer requestId, IResultCallBack<T> resultCallBack) {
        synchronized (this) {
            if (resultCallBack != null) {
                if (chatMsgResultCallBacks == null) {
                    chatMsgResultCallBacks = new HashMap<>();
                }
                chatMsgResultCallBacks.put(requestId, resultCallBack);
            }
        }
    }

    /**
     * 更新本地各个共享属性版本号
     */
    public void updateLocalVersion(JSONObject versionJsonObject) {
        if (versionJsonObject != null) {
            List<String> params = new ArrayList<>();
            Set<String> paramsCache = new HashSet<>();
            for (Map.Entry entry : versionJsonObject.entrySet()) {
                String key = (String) entry.getKey();
                long versionCode = Long.parseLong(entry.getValue().toString());
                Logger.i("key:" + key + ",version:" + versionCode + "，localVersionCode:" + BaseApp.getInstance().getMmkv().decodeLong(key));
                paramsCache.add(key);
                if (BaseApp.getInstance().getMmkv().decodeLong(key) != versionCode) {
                    //更新本地版本号
                    BaseApp.getInstance().getMmkv().encode(key, versionCode);
                    params.add(key);
                }
            }
            if (!params.isEmpty()) {
                Logger.i("Attributes:" + params.toString());
                ApiService.requestAttributes(params);
                BaseApp.getInstance().getMmkv().encode(UploadHotVerWork.ATTRIBUTES, paramsCache);
                WorkManager.getInstance(BaseApp.getInstance()).cancelAllWorkByTag(TAG_UPLOAD_HOT_VER_WORKER);
                OneTimeWorkRequest uploadWorkRequest =
                        new OneTimeWorkRequest.Builder(UploadHotVerWork.class)
                                // Additional configuration
                                .setInitialDelay(30, TimeUnit.SECONDS)
                                .addTag(TAG_UPLOAD_HOT_VER_WORKER)
                                .build();
                WorkManager.getInstance(BaseApp.getInstance())
                        .enqueueUniqueWork(TAG_UPLOAD_HOT_VER_WORKER, ExistingWorkPolicy.REPLACE, uploadWorkRequest);

            }
        }
    }

    public void compareVersionWithLocal(JSONObject versionJsonObject) {
        if (versionJsonObject != null) {
            List<String> params = new ArrayList<>();
            for (Map.Entry entry : versionJsonObject.entrySet()) {
                String key = (String) entry.getKey();
                long versionCode = (long) entry.getValue();
                Logger.i("key:" + key + ",version:" + versionCode);
                if (BaseApp.getInstance().getMmkv().decodeLong(key) != versionCode) {
                    //更新本地版本号
                    BaseApp.getInstance().getMmkv().encode(key, versionCode);
                    params.add(key);
                }
            }
            if (!params.isEmpty() && params.size() > 1) {
                Logger.i("Attributes:" + params.toString());
                ApiService.requestAttributes(params);
            }
        }
    }

    public void updateDeviceConfig(DeviceConfigDTO deviceConfigDTO) {
        DeviceDao deviceDao = AppDataBase.getInstance().deviceDao();
        DeviceConfig lastConfig = deviceDao.queryByDeviceId(AndroidUtils.getDeviceId());
        Logger.d("本地设备信息>>>" + lastConfig);
        Logger.d("服务端设备信息>>>" + deviceConfigDTO);

        int lastState = 0, newState;

        DeviceConfig deviceConfig = new DeviceConfig();
        deviceConfig.setDeviceId(AndroidUtils.getDeviceId());
        deviceConfig.setActiveStatus(deviceConfigDTO.activeStatus);
        deviceConfig.setSimType(deviceConfigDTO.simType);
        deviceConfig.setContractMachine(deviceConfigDTO.contractMachine);
        deviceConfig.setWhiteList(deviceConfigDTO.whiteList);
        deviceConfig.setOffAlarm(deviceConfigDTO.offAlarm);
        deviceConfig.setSceneMode(deviceConfigDTO.sceneMode);
        deviceConfig.setForbiddenShutdown(deviceConfigDTO.forbiddenShutdown);
        deviceConfig.setForbiddenVideoCall(deviceConfigDTO.forbiddenVideoCall);
        deviceConfig.setAutoAnswer(deviceConfigDTO.autoAnswer);
        deviceConfig.setReportCallLocation(deviceConfigDTO.reportCallLocation);
        deviceConfig.setReportShutdownLocation(deviceConfigDTO.reportShutdownLocation);
        deviceConfig.setAutoAnswer(deviceConfigDTO.autoAnswer);
        deviceConfig.setTimeZone(deviceConfigDTO.timeZone);
        deviceConfig.setLocMethod(deviceConfigDTO.locMethod);
        deviceConfig.setCustomGroup(deviceConfigDTO.customGroup);
        deviceConfig.setQimi(deviceConfigDTO.qimi);

        if (lastConfig != null) {
            lastState = lastConfig.getActiveStatus();
            deviceConfig.setInForbidPeriodFlag(lastConfig.isInForbidPeriodFlag());
            deviceConfig.setLaunched(lastConfig.isLaunched());
            deviceConfig.setTheme(lastConfig.getTheme());
            deviceConfig.setWallpaper(lastConfig.getWallpaper());
        }
        //先删除本地数据
        deviceDao.deleteAll();
        //复制本地保存状态的值后再保存数据库
        final long save = deviceDao.save(deviceConfig);
        if (save > 0) {
            DataProvider.DeviceConfigProvider.notifyChange();
        }
        Logger.d("save device config>>>" + save);
        newState = deviceConfig.getActiveStatus();
        Logger.d(">>>合并后设备配置信息>>>" + deviceConfig);

        //情景模式
        //TODO 根据服务器的值来设置情景模式会跟本地配置冲突，所以先设置本地配置再设置情景模式
        //SystemUtils.setRingerMode(BaseApp.getInstance(), deviceConfig.getSceneMode());

        final LauncherManager launcherManager = LauncherManager.getInstance();
        launcherManager.onDeviceConfigChange(deviceConfig);
        if(!Build.DISPLAY.equals(deviceConfigDTO.firmwareVersion)){
            WorkManager.getInstance(BaseApp.getInstance()).cancelAllWorkByTag(TAG_REPORT_DI);
            OneTimeWorkRequest uploadWorkRequest =
                    new OneTimeWorkRequest.Builder(DIWork.class)
                            // Additional configuration
                            .setInitialDelay(5, TimeUnit.SECONDS)
                            .addTag(TAG_REPORT_DI)
                            .build();
            WorkManager.getInstance(BaseApp.getInstance())
                    .enqueueUniqueWork(TAG_REPORT_DI, ExistingWorkPolicy.REPLACE, uploadWorkRequest);
        }

        if (lastState != newState) {
            launcherManager.resetAlarm();
            launcherManager.setTimeZone(deviceConfig.getTimeZone());
            if (newState == 1) {
                Intent intent = new Intent();
                intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES | Intent.FLAG_RECEIVER_FOREGROUND);
                intent.setAction(Constants.ACTION_ACTIVATION);
                BaseApp.getInstance().sendBroadcast(intent);
                Logger.d("设备已绑定");

                //马上定位
                long locFreqId = 0;
                List<LocationPeriod> locationPeriods = AppDataBase.getInstance().locationPeriodDao().queryAll();
                if (locationPeriods.size() > 0) {
                    locFreqId = locationPeriods.get(0).getId();
                }
                LocationService.freqLocation(BaseApp.getInstance().getApplicationContext(), locFreqId);
            } else if (newState == 0) {
                PushReceiverHelper.getInstance().unbind();
            }
        }

        if (DataProvider.isActivated()) {
            if (TextUtils.isEmpty(DataProvider.getHolderId())) {
                //获取HolderInfo
                ApiService.getHolderInfo();
            }
        }
    }

    public void updateLocFrequence(List<LocFrequenceDTO> locFreqList) {
        AppDataBase.getInstance().locationPeriodDao().deleteAll();
        if (locFreqList != null && locFreqList.size() > 0) {
            List<LocationPeriod> locationPeriods = new ArrayList<>();
            for (LocFrequenceDTO locFrequenceDTO : locFreqList) {
                LocationPeriod period = new LocationPeriod();
                period.setId(locFrequenceDTO.id);
                period.setName(locFrequenceDTO.name);
                period.setStartTime(locFrequenceDTO.startTime);
                period.setEndTime(locFrequenceDTO.endTime);
                period.setFreq(locFrequenceDTO.freq);
                period.setRepeatExpression(Utils.isInvalidRepeatExpression(locFrequenceDTO.repeatExpression) ? locFrequenceDTO.repeatExpression : "1111111");
                locationPeriods.add(period);
            }
            AppDataBase.getInstance().locationPeriodDao().save(locationPeriods);
            MMKVUtils.setArray("location_period", locationPeriods);
            Logger.d(">>>save location period success");
            //通知定位广播马上定位
            Intent intent = new Intent();
            intent.setAction(InternalConstant.ACTION_RESET_LOCATION_ALARM);
            intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES | Intent.FLAG_RECEIVER_FOREGROUND);
            BaseApp.getInstance().sendBroadcast(intent);
        }
    }


    public void updatePrayerSetting(PrayerSettingDTO prayerSettingDTO) {
        PrayerSetting localSettings = AppDataBase.getInstance().prayerSettingDao().loadLocalSettings();
        boolean needUpdatePrayerTime = false;
        boolean needUpdatePrayerAlarm = false;
        if (localSettings == null) {
            needUpdatePrayerTime = true;
        } else {
            needUpdatePrayerTime = (prayerSettingDTO.calcMethod.index == 100
                    || prayerSettingDTO.calcMethod.index != localSettings.getIndex()
                    || prayerSettingDTO.asrJuristicMethod != localSettings.getAsrJuristicMethod());
            needUpdatePrayerAlarm = prayerSettingDTO.prayerReminder != localSettings.getPrayerReminder();
        }


        PrayerSetting prayerSetting = new PrayerSetting();
        prayerSetting.setName(prayerSettingDTO.calcMethod.name);
        prayerSetting.setNote(prayerSettingDTO.calcMethod.note);
        prayerSetting.setFajrAngle(prayerSettingDTO.calcMethod.fajrAngle);
        prayerSetting.setMaghribSelector(prayerSettingDTO.calcMethod.maghribSelector);
        prayerSetting.setMaghribValue(prayerSettingDTO.calcMethod.maghribValue);
        prayerSetting.setIshaSelector(prayerSettingDTO.calcMethod.ishaSelector);
        prayerSetting.setIshaValue(prayerSettingDTO.calcMethod.ishaValue);
        prayerSetting.setIndex(prayerSettingDTO.calcMethod.index);
        prayerSetting.setAsrJuristicMethod(prayerSettingDTO.asrJuristicMethod);
        prayerSetting.setAzan(prayerSettingDTO.azan);
        prayerSetting.setPrayerReminder(prayerSettingDTO.prayerReminder);

        AppDataBase.getInstance().prayerSettingDao().deleteAll();
        long result = AppDataBase.getInstance().prayerSettingDao().save(prayerSetting);
        if (result > 0) {
            if(needUpdatePrayerTime){
                BaseApp.getInstance().sendBroadcast(new Intent(Constants.ACTION_UPDATED_PRAYER_TIME));
                return;
            }

            if(needUpdatePrayerAlarm){
                BaseApp.getInstance().sendBroadcast(new Intent(Constants.ACTION_UPDATED_PRAYER_ALARMLIST));
            }
        }
    }


    public void updateHolderInfo(HolderInfoDTO holderInfoDTO) {
        HolderInfo holderInfo = new HolderInfo();
        holderInfo.setHolderId(holderInfoDTO.holderId);
        holderInfo.setDeviceId(AndroidUtils.getDeviceId());
        holderInfo.setName(holderInfoDTO.name);
        holderInfo.setAvatar(holderInfoDTO.avatar);
        holderInfo.setGender(holderInfoDTO.gender);
        holderInfo.setHeight(holderInfoDTO.height);
        holderInfo.setWeight(holderInfoDTO.weight);
        holderInfo.setBirthday(holderInfoDTO.birthday);
        holderInfo.setStepPlanValue(holderInfoDTO.stepPlanValue);
        holderInfo.setSportsChallengeRewardsValue(holderInfoDTO.sportChallengeTotalRewardValue);
        holderInfo.setQuranLearnTotalRewardValue(holderInfoDTO.quranLearnTotalRewardValue);
        holderInfo.setChantsCounterTotal(holderInfoDTO.chantsCounterTotal);
        holderInfo.setChantsCounterChallengeTotal(holderInfoDTO.chantsCounterChallengeTotal);
        AppDataBase.getInstance().holderInfoDao().deleteAll();
        long result = AppDataBase.getInstance().holderInfoDao().save(holderInfo);
        if (result > 0) {
            //通知监听器，数据已经改变
            DataProvider.HolderInfoProvider.notifyChange();
        }
    }

    public void updateContacts(List<ContactDTO> contactDTOList) {
        ContactDao contactDao = AppDataBase.getInstance().contactDao();
        AsyncTask.execute(() -> {
            List<ContactInfo> dbContacts = contactDao.queryAll();
            if (contactDTOList == null || contactDTOList.isEmpty()) {
                contactDao.deleteAll();
            } else {
                List<ContactInfo> tempContacts = new ArrayList<>(contactDTOList.size());
                for (ContactDTO item : contactDTOList) {
                    ContactInfo contactInfo = new ContactInfo();
                    contactInfo.setContactId(item.id);
                    contactInfo.setName(item.name);
                    contactInfo.setPhone(item.phone);
                    contactInfo.setPhotoUrl(item.avatar);
                    contactInfo.setType(item.type);
                    contactInfo.setFriendId(item.memberId);
                    tempContacts.add(contactInfo);
                }

                deletePhoneContacts(dbContacts);
                dbContacts.removeAll(tempContacts);
                contactDao.delete(dbContacts);
                savePhoneContacts(tempContacts);
                //保存联系人
                contactDao.save(tempContacts);
                Logger.d(">>>保存联系人>>>" + tempContacts);
                DataProvider.ContactProvider.notifyChange();
            }
        });
    }

    public void updateIMGroup(List<IMGroupDTO> imGroupDTOList) {
        IMGroupDao imGroupDao = AppDataBase.getInstance().iMGroupDao();
        GroupMemberDao groupMemberDao = AppDataBase.getInstance().groupMemberDao();
        AsyncTask.execute(() -> {
            List<IMGroup> dbIMGroup = imGroupDao.queryAll();
            HashMap<String,String> adminMap = new HashMap<>();
            if (imGroupDTOList == null || imGroupDTOList.isEmpty()) {
                imGroupDao.deleteAll();
                groupMemberDao.deleteAll();
            } else {
                List<IMGroup> tempIMGroup = new ArrayList<>(imGroupDTOList.size());
                List<IMGroupMember> tempIMGroupMembers = new ArrayList<>();
                for (IMGroupDTO item : imGroupDTOList) {
                    IMGroup imGroup = new IMGroup();
                    imGroup.setId(item.id);
                    imGroup.setType(item.type);
                    imGroup.setName(item.name);
                    imGroup.setAvatar(item.avatar);
                    imGroup.setCreateTime(item.createTime);
                    tempIMGroup.add(imGroup);
                    for (IMGroupDTO.GroupMemberListDTO groupMemberListDTO : item.groupMemberList) {
                        IMGroupMember imGroupMember = new IMGroupMember();
                        imGroupMember.setMemberId(groupMemberListDTO.memberId);
                        imGroupMember.setGroupId(item.id);
                        imGroupMember.setName(groupMemberListDTO.name);
                        imGroupMember.setType(groupMemberListDTO.type);
                        imGroupMember.setAvatar(groupMemberListDTO.avatar);
                        imGroupMember.setAvatarIndex(groupMemberListDTO.avatarIndex);
                        imGroupMember.setCreateTime(groupMemberListDTO.createTime);
                        tempIMGroupMembers.add(imGroupMember);
                        if (groupMemberListDTO.type == 0) {
                            //如果是群主的话 存储每个群组的群主id
                            adminMap.put(item.id,groupMemberListDTO.memberId);
                        }
                    }
                }
                dbIMGroup.removeAll(tempIMGroup);
                if (!dbIMGroup.isEmpty()) {
                    imGroupDao.delete(dbIMGroup);
                    //TODO 看情况是否删除群聊天记录
                }
                imGroupDao.save(tempIMGroup);
                groupMemberDao.deleteAll();
                groupMemberDao.save(tempIMGroupMembers);


                ArrayList<ContentProviderOperation> list = new ArrayList<>();
                for (IMGroup imGroup : tempIMGroup) {
                    ContentValues values = new ContentValues();
                    values.put(DataProvider.ChatContactProvider.FRIEND_ID, imGroup.getId());
                    values.put(DataProvider.ChatContactProvider.FRIEND_TYPE, imGroup.getType());
                    values.put(DataProvider.ChatContactProvider.NAME, imGroup.getName());
                    values.put(DataProvider.ChatContactProvider.AVATAR, imGroup.getAvatar());
                    values.put(DataProvider.ChatContactProvider.CREATE_TIME, imGroup.getCreateTime());
                    String adminId = adminMap.get(imGroup.getId());
                    boolean isAdmin = adminId != null && BaseApp.getInstance().getHolderId().equalsIgnoreCase(adminId);
                    values.put(DataProvider.ChatContactProvider.IS_ADMIN, isAdmin);
                    values.put(DataProvider.ChatContactProvider.IS_GROUP, true);
                    final ContentProviderOperation operation = ContentProviderOperation
                            .newInsert(DataProvider.ChatContactProvider.getUri())
                            .withValues(values).build();
                    list.add(operation);
                }
                try {
                    BaseApp.getInstance().getContentResolver().applyBatch(DataProvider.ChatContactProvider.AUTHORITY, list);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                BaseApp.getInstance().setupChatDataBaseService();
                Logger.d(">>>保存好友>>>" + tempIMGroup);
            }
        });
    }


    public void updateBuddy(List<BuddyDTO> buddyDTOList) {
        BuddyDao buddyDao = AppDataBase.getInstance().buddyDao();
        AsyncTask.execute(() -> {
            List<BuddyInfo> dbBuddies = buddyDao.queryAll();
            if (buddyDTOList == null || buddyDTOList.isEmpty()) {
                buddyDao.deleteAll();
            } else {
                List<BuddyInfo> tempBuddies = new ArrayList<>(buddyDTOList.size());
                for (BuddyDTO item : buddyDTOList) {
                    BuddyInfo buddyInfo = new BuddyInfo();
                    buddyInfo.setFriendId(item.memberId);
                    buddyInfo.setType(item.type);
                    buddyInfo.setName(item.name);
                    buddyInfo.setAvatar(item.avatar);
                    buddyInfo.setCreateTime(item.createTime);
                    buddyInfo.setHiddenFeatures(item.hiddenFeatures);
                    buddyInfo.isAdmin = item.type == 0;
                    tempBuddies.add(buddyInfo);
                }
                dbBuddies.removeAll(tempBuddies);
                if (!dbBuddies.isEmpty()) {
                    buddyDao.delete(dbBuddies);
                }
                buddyDao.save(tempBuddies);

                ArrayList<ContentProviderOperation> list = new ArrayList<>();
                for (BuddyInfo buddyInfo : tempBuddies) {
                    ContentValues values = new ContentValues();
                    values.put(DataProvider.ChatContactProvider.FRIEND_ID, buddyInfo.getFriendId());
                    values.put(DataProvider.ChatContactProvider.FRIEND_TYPE, buddyInfo.getType());
                    values.put(DataProvider.ChatContactProvider.NAME, buddyInfo.getName());
                    values.put(DataProvider.ChatContactProvider.AVATAR, buddyInfo.getAvatar());
                    values.put(DataProvider.ChatContactProvider.CREATE_TIME, buddyInfo.getCreateTime());
                    values.put(DataProvider.ChatContactProvider.IS_ADMIN, buddyInfo.isAdmin);
                    values.put(DataProvider.ChatContactProvider.IS_GROUP, false);
                    final ContentProviderOperation operation = ContentProviderOperation
                            .newInsert(DataProvider.ChatContactProvider.getUri())
                            .withValues(values).build();
                    list.add(operation);
                }
                try {
                    BaseApp.getInstance().getContentResolver().applyBatch(DataProvider.ChatContactProvider.AUTHORITY, list);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                BaseApp.getInstance().setupChatDataBaseService();
                Logger.d(">>>保存好友>>>" + tempBuddies);
            }
        });
    }

    private void updateQuranLearnChallenge(List<QuranLearnChallengeDTO> quranLearnChallengeDTOList) {
        AppDataBase.getInstance().quranLearnDao().deleteAll();
        ArrayList<QuranLearn> list = new ArrayList<>();
        for (QuranLearnChallengeDTO quranLearnChallengeDTO : quranLearnChallengeDTOList) {
            QuranLearn quranLearn = new QuranLearn();
            quranLearn.setId(quranLearnChallengeDTO.id);
            quranLearn.setChapterIndex(quranLearnChallengeDTO.chapterIndex);
            quranLearn.setDuration(quranLearnChallengeDTO.duration);
            quranLearn.setDeadline(quranLearnChallengeDTO.deadline);
            quranLearn.setRewardValue(quranLearnChallengeDTO.rewardValue);
            list.add(quranLearn);
        }
        AppDataBase.getInstance().quranLearnDao().save(list);
        Logger.d(">>>保存古兰经挑战>>>" + list);
        DataProvider.QuranLearnProvider.notifyChange();
    }

    private void updateTasks(List<TasksAttributeDTO> tasksAttributeDTOList) {
        TasksAttributeDao tasksAttributeDao = AppDataBase.getInstance().tasksAttributeDao();
        Logger.d(">>>delete all tasks>>>" + tasksAttributeDao.deleteAll());
        if (tasksAttributeDTOList != null && !tasksAttributeDTOList.isEmpty()) {
            ArrayList<TasksAttribute> list = new ArrayList<>();
            for (TasksAttributeDTO tasksAttributeDTO : tasksAttributeDTOList) {
                TasksAttribute tasksAttribute = new TasksAttribute();
                tasksAttribute.id = tasksAttributeDTO.id;
                tasksAttribute.type = tasksAttributeDTO.type;
                tasksAttribute.action = tasksAttributeDTO.action;
                tasksAttribute.title = tasksAttributeDTO.title;
                tasksAttribute.content = tasksAttributeDTO.content;
                tasksAttribute.reminderTime = tasksAttributeDTO.reminderTime;
                tasksAttribute.repeatExpression = tasksAttributeDTO.repeatExpression;
                tasksAttribute.additionalInfo = GsonUtils.toJson(tasksAttributeDTO.additionalInfo);
                list.add(tasksAttribute);
            }
            tasksAttributeDao.save(list);
        }
        BaseApp.getInstance().sendBroadcast(new Intent(Constants.ACTION_UPDATED_TASK_LIST));
    }


    public void updateSportsChallenge(List<SportChallengeDTO> sportChallengeDTOList) {
        try {
            DataProvider.deleteAllSportsChallenge();
            ArrayList<ContentProviderOperation> list = new ArrayList<>();
            for (SportChallengeDTO sportChallengeDTO : sportChallengeDTOList) {
                ContentValues values = new ContentValues();
                values.put(DataProvider.SportsChallengeProvider.ID, sportChallengeDTO.id);
                values.put(DataProvider.SportsChallengeProvider.SPORTS_TYPE, sportChallengeDTO.sportType);
                values.put(DataProvider.SportsChallengeProvider.DURATION, sportChallengeDTO.duration);
                values.put(DataProvider.SportsChallengeProvider.REMINDER_TIME, sportChallengeDTO.reminderTime);
                values.put(DataProvider.SportsChallengeProvider.REWARDS_VALUE, sportChallengeDTO.rewardValue);
                final ContentProviderOperation operation = ContentProviderOperation
                        .newInsert(DataProvider.SportsChallengeProvider.getUri())
                        .withValues(values).build();
                list.add(operation);
            }
            try {
                BaseApp.getInstance().getContentResolver().applyBatch(DataProvider.SportsChallengeProvider.AUTHORITY, list);
                DataProvider.SportsChallengeProvider.notifyChange();
            } catch (Exception e) {
                e.printStackTrace();
            }
            BaseApp.getInstance().sendBroadcast(new Intent("com.umeox.moto.intent.action.UPDATE_ALARM_LIST"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void updateAlarms(List<AlarmDTO> alarmDTOList) {
        AlarmDao alarmDao = AppDataBase.getInstance().alarmDao();
        Logger.d(">>>delete remote alarm clock>>>" + alarmDao.deleteAllRemote());
        if (alarmDTOList != null && !alarmDTOList.isEmpty()) {
            List<AlarmClock> alarmClockList = new ArrayList<>(alarmDTOList.size());
            for (AlarmDTO dto : alarmDTOList) {
                AlarmClock clock = new AlarmClock();
                clock.alarmId = dto.id;
                clock.alarmName = dto.name;
                clock.alarmTime = dto.alarmTime;
                clock.repeatFlag = dto.repeatFlag;
                clock.repeatExpression = dto.repeatExpression;
                clock.ringType = dto.ringType;
                clock.ringSrc = dto.ringSrc;
                clock.state = 1;
                alarmClockList.add(clock);
            }
            alarmDao.save(alarmClockList);
        }
        BaseApp.getInstance().sendBroadcast(new Intent(Constants.ACTION_UPDATED_ALARMLIST));
    }


    public void updateClassMode(List<ForbidPeriodDTO> forbidPeriodDTOList) {
        ForbidPeriodDao forbidPeriodDao = AppDataBase.getInstance().forbidPeriodDao();
        //先清除本地的上课时段
        forbidPeriodDao.deleteAll();
        List<ForbidPeriod> forbidPeriodList = null;
        if (forbidPeriodDTOList != null && !forbidPeriodDTOList.isEmpty()) {
            forbidPeriodList = new ArrayList<>(forbidPeriodDTOList.size());
            for (ForbidPeriodDTO forbidPeriodDTO : forbidPeriodDTOList) {
                ForbidPeriod forbidPeriod = new ForbidPeriod();
                forbidPeriod.setId(forbidPeriodDTO.id);
                forbidPeriod.setDeviceId(AndroidUtils.getDeviceId());
                forbidPeriod.setName(forbidPeriodDTO.name);
                forbidPeriod.setTimePeriod(String.format("%s-%s", forbidPeriodDTO.startTime, forbidPeriodDTO.endTime));
                forbidPeriod.setRepeatExpression(forbidPeriodDTO.repeatExpression);
                forbidPeriodList.add(forbidPeriod);
            }
            forbidPeriodDao.save(forbidPeriodList);
        }
        LauncherManager.getInstance().setForbidPeriods(forbidPeriodList);
    }


    public void updateFences(List<FencesDTO> fencesDTOList) {
        FencesDao fencesDao = AppDataBase.getInstance().fencesDao();
        fencesDao.deleteAll();
        if (fencesDTOList != null && !fencesDTOList.isEmpty()) {
            List<Fences> fencesList = new ArrayList<>(fencesDTOList.size());
            for (FencesDTO fencesDTO : fencesDTOList) {
                Fences fences = new Fences();
                fences.setId(fencesDTO.id);
                fences.setName(fencesDTO.name);
                fences.setType(fencesDTO.type);
                fences.setCoordType(fencesDTO.coordType);
                fences.setLat(fencesDTO.lat);
                fences.setLng(fencesDTO.lng);
                fences.setRadius(fencesDTO.radius);
                fences.setVertexes(fencesDTO.vertexes);
                fences.setOffset(fencesDTO.distanceOffset);
                fences.setRepeatExpression(fencesDTO.repeatExpression);
                fences.setStartTime(fencesDTO.startTime);
                fences.setEndTime(fencesDTO.endTime);
                fences.setEnterAlarm(fencesDTO.enterAlarm);
                fences.setLeaveAlarm(fencesDTO.leaveAlarm);
                Logger.i(fences.toString());
                fencesList.add(fences);
            }
            fencesDao.save(fencesList);
        }
        GeoFenceService.setGeoFence(BaseApp.getInstance().getApplicationContext());
    }

    public void configWifi(List<WifiDTO> wifiInfos) {
        if (wifiInfos != null && !wifiInfos.isEmpty()) {
            final boolean isWifiEnabled = NetUtils.isWifiEnabled();
            if (!isWifiEnabled) {
                Logger.i(">>>保存App设置的WIFI信息，需要先打开WIFI");
                NetUtils.setWifiEnabled(true);
            }
            for (WifiDTO wifiInfo : wifiInfos) {
                NetUtils.saveNetwork(wifiInfo.ssid, wifiInfo.password);
            }
            if (!isWifiEnabled) {
                Logger.i(">>>保存App设置的WIFI信息完成，关闭WIFI");
                NetUtils.setWifiEnabled(false);
            }
        }
    }


    /**
     * 处理二维码
     */
    public void saveOrUpdateBindCode(DeviceCodeDTO deviceCodeDTO) {
        DeviceCodeDao deviceCodeDao = AppDataBase.getInstance().deviceCodeDao();
        DeviceCode deviceCode = deviceCodeDao.queryByDeviceId(AndroidUtils.getDeviceId());
        deviceCodeDao.deleteAll();
        if (deviceCode != null) {
            deviceCode.setQrCode(deviceCodeDTO.qrCode);
            deviceCode.setBindCode(deviceCodeDTO.bindCode);
            deviceCode.setExpiredTime(deviceCodeDTO.expiredTime);
            deviceCodeDao.save(deviceCode);
        } else {
            deviceCodeDao.save(DeviceCode.covertDeviceCode(deviceCodeDTO));
        }
        DataProvider.DeviceCodeProvider.notifyChange();
    }


    @SuppressWarnings("unchecked")
    public void handleSOSEvent(SOSEventDTO sosEventDTO) {
        if (mResultCallBack != null) {
            mResultCallBack.onResult((T) sosEventDTO);
        }
    }

    @SuppressWarnings("unchecked")
    public void handleMakeFriend(Integer code) {
        if (mResultCallBack != null) {
            mResultCallBack.onResult((T) code);
        }
    }

    @SuppressWarnings("unchecked")
    public void handleChatMsg(Integer requestId, String msgId) {
        synchronized (this) {
            if (chatMsgResultCallBacks != null) {
                IResultCallBack<T> currentChatMsgCallBack = chatMsgResultCallBacks.get(requestId);
                if (currentChatMsgCallBack != null) {
                    currentChatMsgCallBack.onResult((T) msgId);
                    chatMsgResultCallBacks.remove(requestId);
                }
            }
        }
    }

    /**
     * 设备没有任何数据的情况处理
     */
    public void handleNotInitDevice() {
        //设备还没有初始化数据，通知launcher到二维码界面
        Intent intent = new Intent();
        intent.setAction(Constants.ACTION_DEVICE_NOT_INIT);
        intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES | Intent.FLAG_RECEIVER_FOREGROUND);
        BaseApp.getInstance().sendBroadcast(intent);
    }


    public void updateData(String attribute, PayloadMessage payloadMessage) {
        if (MqttConstants.Attributes.DEVICE_CONFIG.equals(attribute)) {
            JSONObject deviceConfigJsonObject = (JSONObject) payloadMessage.getProperty(MqttConstants.Attributes.DEVICE_CONFIG);
            DeviceConfigDTO deviceConfigDTO = JSONObject.toJavaObject(deviceConfigJsonObject, DeviceConfigDTO.class);
            updateDeviceConfig(deviceConfigDTO);
        } else if (MqttConstants.Attributes.LOCATION_FREQ.equals(attribute)) {
            JSONArray jsonArray = (JSONArray) payloadMessage.getProperty(MqttConstants.Attributes.LOCATION_FREQ);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<LocFrequenceDTO> locFrequenceDTO = JSONObject.parseArray(jsonStr, LocFrequenceDTO.class);
            updateLocFrequence(locFrequenceDTO);
        } else if (MqttConstants.Attributes.CONTACTS.equals(attribute)) {
            JSONArray jsonArray = (JSONArray) payloadMessage.getProperty(MqttConstants.Attributes.CONTACTS);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<ContactDTO> contactDTOList = JSONObject.parseArray(jsonStr, ContactDTO.class);
            updateContacts(contactDTOList);
        } else if (MqttConstants.Attributes.FRIENDS.equals(attribute)) {
            JSONArray jsonArray = (JSONArray) payloadMessage.getProperty(MqttConstants.Attributes.FRIENDS);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<BuddyDTO> buddyDTOList = JSONObject.parseArray(jsonStr, BuddyDTO.class);
            updateBuddy(buddyDTOList);
        } else if (MqttConstants.Attributes.IM_GROUP.equals(attribute)) {
            JSONArray jsonArray = (JSONArray) payloadMessage.getProperty(MqttConstants.Attributes.IM_GROUP);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<IMGroupDTO> imGroupDTOList = JSONObject.parseArray(jsonStr, IMGroupDTO.class);
            updateIMGroup(imGroupDTOList);
        } else if (MqttConstants.Attributes.HOLDER_INFO.equals(attribute)) {
            JSONObject holderInfoJsonObject = (JSONObject) payloadMessage.getProperty(MqttConstants.Attributes.HOLDER_INFO);
            HolderInfoDTO holderInfoDTO = JSONObject.toJavaObject(holderInfoJsonObject, HolderInfoDTO.class);
            Logger.e("holderInfoDTO->" + holderInfoDTO.toString());
            updateHolderInfo(holderInfoDTO);
        } else if (MqttConstants.Attributes.ALARM.equals(attribute)) {
            JSONArray jsonArray = (JSONArray) payloadMessage.getProperty(MqttConstants.Attributes.ALARM);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<AlarmDTO> alarmDTOList = JSONObject.parseArray(jsonStr, AlarmDTO.class);
            updateAlarms(alarmDTOList);
        } else if (MqttConstants.Attributes.CLASS_MODE.equals(attribute)) {
            JSONArray jsonArray = (JSONArray) payloadMessage.getProperty(MqttConstants.Attributes.CLASS_MODE);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<ForbidPeriodDTO> forbidPeriodDTOList = JSONObject.parseArray(jsonStr, ForbidPeriodDTO.class);
            updateClassMode(forbidPeriodDTOList);
        } else if (MqttConstants.Attributes.FENCES.equals(attribute)) {
            JSONArray jsonArray = (JSONArray) payloadMessage.getProperty(MqttConstants.Attributes.FENCES);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<FencesDTO> fencesDTOList = JSONObject.parseArray(jsonStr, FencesDTO.class);
            updateFences(fencesDTOList);
        } else if (MqttConstants.Attributes.SPORT_CHALLENGE.equals(attribute)) {
            JSONArray jsonArray = (JSONArray) payloadMessage.getProperty(MqttConstants.Attributes.SPORT_CHALLENGE);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<SportChallengeDTO> sportChallengeDTOList = JSONObject.parseArray(jsonStr, SportChallengeDTO.class);
            updateSportsChallenge(sportChallengeDTOList);
        } else if (MqttConstants.Attributes.PRAYER_SETTING.equals(attribute)) {
            JSONObject prayerSettingJsonObject = (JSONObject) payloadMessage.getProperty(MqttConstants.Attributes.PRAYER_SETTING);
            PrayerSettingDTO prayerSettingDTO = JSONObject.toJavaObject(prayerSettingJsonObject, PrayerSettingDTO.class);
            Logger.e("prayerSettingDTO->" + prayerSettingDTO.toString());
            updatePrayerSetting(prayerSettingDTO);
        } else if (MqttConstants.Attributes.QURAN_LEARN.equals(attribute)) {
            JSONArray jsonArray = (JSONArray) payloadMessage.getProperty(MqttConstants.Attributes.QURAN_LEARN);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<QuranLearnChallengeDTO> quranLearnChallengeDTOList = JSONObject.parseArray(jsonStr, QuranLearnChallengeDTO.class);
            updateQuranLearnChallenge(quranLearnChallengeDTOList);
        } else if (MqttConstants.Attributes.TASKS.equals(attribute)) {
            JSONArray jsonArray = (JSONArray) payloadMessage.getProperty(MqttConstants.Attributes.TASKS);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<TasksAttributeDTO> tasksAttributeDTOList = JSONObject.parseArray(jsonStr, TasksAttributeDTO.class);
            updateTasks(tasksAttributeDTOList);
        }
    }



    public void updateData(JSONObject jsonObject) {
        if (jsonObject.containsKey(MqttConstants.Attributes.DEVICE_CONFIG)) {
            DeviceConfigDTO deviceConfigDTO = jsonObject.getObject(MqttConstants.Attributes.DEVICE_CONFIG, DeviceConfigDTO.class);
            updateDeviceConfig(deviceConfigDTO);
        }

        if (jsonObject.containsKey(MqttConstants.Attributes.HOLDER_INFO)) {
            HolderInfoDTO holderInfoDTO = jsonObject.getObject(MqttConstants.Attributes.HOLDER_INFO, HolderInfoDTO.class);
            updateHolderInfo(holderInfoDTO);
        }

        if (jsonObject.containsKey(MqttConstants.Attributes.CONTACTS)) {
            JSONArray jsonArray = jsonObject.getJSONArray(MqttConstants.Attributes.CONTACTS);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<ContactDTO> contactDTOList = JSONObject.parseArray(jsonStr, ContactDTO.class);
            updateContacts(contactDTOList);
        }

        if (jsonObject.containsKey(MqttConstants.Attributes.FRIENDS)) {
            JSONArray jsonArray = jsonObject.getJSONArray(MqttConstants.Attributes.FRIENDS);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<BuddyDTO> buddyDTOList = JSONObject.parseArray(jsonStr, BuddyDTO.class);
            updateBuddy(buddyDTOList);
        }

        if (jsonObject.containsKey(MqttConstants.Attributes.IM_GROUP)) {
            JSONArray jsonArray = jsonObject.getJSONArray(MqttConstants.Attributes.IM_GROUP);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<IMGroupDTO> imGroupDTOList = JSONObject.parseArray(jsonStr, IMGroupDTO.class);
            updateIMGroup(imGroupDTOList);
        }

        if (jsonObject.containsKey(MqttConstants.Attributes.LOCATION_FREQ)) {
            JSONArray jsonArray = jsonObject.getJSONArray(MqttConstants.Attributes.LOCATION_FREQ);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<LocFrequenceDTO> locFrequenceDTOList = JSONObject.parseArray(jsonStr, LocFrequenceDTO.class);
            updateLocFrequence(locFrequenceDTOList);
        }

        if (jsonObject.containsKey(MqttConstants.Attributes.ALARM)) {
            JSONArray jsonArray = jsonObject.getJSONArray(MqttConstants.Attributes.ALARM);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<AlarmDTO> alarmDTOList = JSONObject.parseArray(jsonStr, AlarmDTO.class);
            updateAlarms(alarmDTOList);
        }

        if (jsonObject.containsKey(MqttConstants.Attributes.CLASS_MODE)) {
            JSONArray jsonArray = jsonObject.getJSONArray(MqttConstants.Attributes.CLASS_MODE);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<ForbidPeriodDTO> forbidPeriodDTOList = JSONObject.parseArray(jsonStr, ForbidPeriodDTO.class);
            updateClassMode(forbidPeriodDTOList);
        }

        if (jsonObject.containsKey(MqttConstants.Attributes.WIFI_CONFIG)) {
            JSONArray jsonArray = jsonObject.getJSONArray(MqttConstants.Attributes.WIFI_CONFIG);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<WifiDTO> wifiDTOList = JSONObject.parseArray(jsonStr, WifiDTO.class);
            configWifi(wifiDTOList);
        }

        if (jsonObject.containsKey(MqttConstants.Attributes.FENCES)) {
            JSONArray jsonArray = jsonObject.getJSONArray(MqttConstants.Attributes.FENCES);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<FencesDTO> fencesDTOList = JSONObject.parseArray(jsonStr, FencesDTO.class);
            updateFences(fencesDTOList);
        }


        if (jsonObject.containsKey(MqttConstants.Attributes.SPORT_CHALLENGE)) {
            JSONArray jsonArray = jsonObject.getJSONArray(MqttConstants.Attributes.SPORT_CHALLENGE);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<SportChallengeDTO> sportChallengeDTOList = JSONObject.parseArray(jsonStr, SportChallengeDTO.class);
            updateSportsChallenge(sportChallengeDTOList);
        }

        if (jsonObject.containsKey(MqttConstants.Attributes.PRAYER_SETTING)) {
            PrayerSettingDTO prayerSettingDTO = jsonObject.getObject(MqttConstants.Attributes.PRAYER_SETTING, PrayerSettingDTO.class);
            Logger.e("prayerSettingDTO->" + prayerSettingDTO.toString());
            updatePrayerSetting(prayerSettingDTO);
        }

        if (jsonObject.containsKey(MqttConstants.Attributes.QURAN_LEARN)) {
            JSONArray jsonArray = jsonObject.getJSONArray(MqttConstants.Attributes.QURAN_LEARN);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<QuranLearnChallengeDTO> quranLearnChallengeDTOList = JSONObject.parseArray(jsonStr, QuranLearnChallengeDTO.class);
            updateQuranLearnChallenge(quranLearnChallengeDTOList);
        }

        if (jsonObject.containsKey(MqttConstants.Attributes.TASKS)) {
            JSONArray jsonArray = jsonObject.getJSONArray(MqttConstants.Attributes.TASKS);
            String jsonStr = JSONObject.toJSONString(jsonArray);
            List<TasksAttributeDTO> tasksAttributeDTOList = JSONObject.parseArray(jsonStr, TasksAttributeDTO.class);
            updateTasks(tasksAttributeDTOList);
        }
    }
}
